# coding=utf-8
"""

1. 以Lena为原始图像，通过OpenCV实现平均滤波，高斯滤波及中值滤波，比较滤波结果。
结果分析：
1）对平均滤波、高斯滤波和中值滤波器均设置卷积核大小为 5*5，通过人眼分析运行结果图像，很明显，通过高斯滤波后，Lena 的睫毛和瞳孔依然比较清晰，而且帽子的纹路也仍然可以看清楚，反观其他两个就不是很清楚了，特别是平均滤波后的 Lena 整体呈现模糊的状态。通过察看 Lena 的帽子边缘可以看出，中值滤波后的边缘最为清晰。总体分析，高斯滤波效果最好，其次是中值滤波，最后是平均滤波。
2）对平均滤波、高斯滤波和中值滤波器设置不同卷积核大小时，例如，通过人眼分析运行结果图像，很明显，通过高斯滤波后，Lena 的睫毛和瞳孔依然比较清晰，而且帽子的纹路也仍然可以看清楚，反观其他两个就不是很清楚了，特别是平均滤波后的 Lena 整体呈现模糊的状态。通过察看 Lena 的帽子边缘可以看出，中值滤波后的边缘最为清晰。总体分析，高斯滤波效果最好，其次是中值滤波，最后是平均滤波。

"""

import cv2 as cv

LenaFilename = r'lena.jpg'

# 1）对平均滤波、高斯滤波和中值滤波器均设置卷积核大小为 5*5，通过人眼分析运行结果图像，很明显，通过高斯滤波后，Lena 的睫毛和瞳孔依然比较清晰，而且帽子的纹路也仍然可以看清楚，反观其他两个就不是很清楚了，特别是平均滤波后的 Lena 整体呈现模糊的状态。通过察看 Lena 的帽子边缘可以看出，中值滤波后的边缘最为清晰。总体分析，高斯滤波效果最好，其次是中值滤波，最后是平均滤波。
img = cv.imread(LenaFilename)
imgGauss = cv.GaussianBlur(img, (5, 5), 0)  # 高斯滤波: 注意的是a*b必须是奇数
imgblur = cv.blur(img, (5, 5))  # 均值滤波: 5*5的平均滤波器
medianBlur = cv.medianBlur(img, 5)  # 中值滤波: 第二个参数必须是基数且大于1，因为中值滤波就是将投射面排列取中间那个值

cv.imshow("Source", img)  # 运行结果:  https://gitee.com/skyrookieyu/csdn_ai25_week2/blob/master/1_1.JPG
cv.imshow("Gaussian", imgGauss)  # 运行结果:  https://gitee.com/skyrookieyu/csdn_ai25_week2/blob/master/1_2.JPG
cv.imshow("Blur", imgblur)  # 运行结果:  https://gitee.com/skyrookieyu/csdn_ai25_week2/blob/master/1_3.JPG
cv.imshow("MedianBlur", medianBlur)  # 运行结果:  https://gitee.com/skyrookieyu/csdn_ai25_week2/blob/master/1_4.JPG
cv.waitKey()
cv.destroyAllWindows()#显示图像

# 2）对平均滤波、高斯滤波和中值滤波器设置不同卷积核大小时，例如下面的示例，通过人眼分析运行结果图像，很明显，通过中值滤波后，Lena 的睫毛和瞳孔依然比较清晰，而且帽子的纹路也仍然可以看清楚，反观其他两个就不是很清楚了，特别是平均滤波后的 Lena 整体呈现模糊的状态。通过察看 Lena 的帽子边缘可以看出，中值滤波后的边缘最为清晰。总体分析，中值滤波效果最好，其次是高斯滤波，最后是平均滤波。
imgGauss2 = cv.GaussianBlur(img, (5, 5), 0)  # 高斯滤波: 注意的是a*b必须是奇数
imgblur2 = cv.blur(img, (1, 15))  # 均值滤波: 1*15的平均滤波器
medianBlur2 = cv.medianBlur(img, 3)  # 中值滤波: 第二个参数必须是基数且大于1，因为中值滤波就是将投射面排列取中间那个值

cv.imshow("Source", img)  # 运行结果:  https://gitee.com/skyrookieyu/csdn_ai25_week2/blob/master/1_5.JPG
cv.imshow("Gaussian", imgGauss2)  # 运行结果:  https://gitee.com/skyrookieyu/csdn_ai25_week2/blob/master/1_6.JPG
cv.imshow("Blur", imgblur2)  # 运行结果:  https://gitee.com/skyrookieyu/csdn_ai25_week2/blob/master/1_7.JPG
cv.imshow("MedianBlur", medianBlur2)  # 运行结果:  https://gitee.com/skyrookieyu/csdn_ai25_week2/blob/master/1_8.JPG
cv.waitKey()
cv.destroyAllWindows()  # 显示图像

# 3) 综合分析：不同的卷积核大小会影响滤波的效果，实际运用的时候还是应该遵循目的和图片本身的特性去选择合适的算法与卷积核尺寸。
#             高斯平滑在图像平滑处理中表现较好，也是非常常用的一种滤波方式。中值滤波有利于椒盐噪声的处理，还有一定的保边作用。而平均滤波表现出的效果就感觉没有那么好。

######### ----------------------------------------  #########

# coding=utf-8
"""

2. 以Lena为原始图像，通过OpenCV使用Sobel及Canny算子检测，比较边缘检测结果。
结果分析：
Sobel算子检测由x轴，y轴分别计算然后合成的效果最佳，边缘检测较明显。
Canny算子边缘检测效果较明显，阈值二值化处理，极大值抑制使图像边缘与其他区域区分更加明显。
Sobel算子效果不错，Canny算子效果则更明显。

"""

import cv2 as cv

LenaFilename = r'lena.jpg'

img = cv.imread(LenaFilename)
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)

# Sobel 算子边缘检测
deltax = cv.Sobel(gray, cv.CV_32F, 1, 0)  # X方向的差异
deltay = cv.Sobel(gray, cv.CV_32F, 0, 1)  # Y方向的差异
adsX = cv.convertScaleAbs(deltax)
adsY = cv.convertScaleAbs(deltay)
dst = cv.addWeighted(adsX, 0.5, adsY, 0.5, 0)

cv.imshow("X", adsX)  # 运行结果:  https://gitee.com/skyrookieyu/csdn_ai25_week2/blob/master/2_1.JPG
cv.imshow("Y", adsY)  # 运行结果:  https://gitee.com/skyrookieyu/csdn_ai25_week2/blob/master/2_2.JPG
cv.imshow("Sobel", dst)  # 运行结果:  https://gitee.com/skyrookieyu/csdn_ai25_week2/blob/master/2_3.JPG

# Canny算子边缘检测
canny50 = cv.Canny(gray, 50, 120)
canny80 = cv.Canny(gray, 80, 120)
cv.imshow('Canny50_120', canny50)  # 运行结果:  https://gitee.com/skyrookieyu/csdn_ai25_week2/blob/master/2_4.JPG
cv.imshow('Canny80_120', canny80)  # 运行结果:  https://gitee.com/skyrookieyu/csdn_ai25_week2/blob/master/2_5.JPG

cv.waitKey()
cv.destroyAllWindows()

######### ----------------------------------------  #########

# coding=utf-8
"""

3. 在OpenCV安装目录下找到课程对应演示图片(安装目录\sources\samples\data)，首先计算灰度直方图，进一步使用大津算法进行分割，并比较分析分割结果。
结果分析：
两幅图像的灰度直方图如图。
使用局部大津算法阈值分割，再使用形态学以及开运算去辅助处理图像，阈值分割效果明显，但是渐变色度的图像使用大津算法并没有很好的效果，是由于大津算法采用全局阈值。

"""

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt

img1 = cv.imread(r'pic2.png')  # 读取图像
img2 = cv.imread(r'pic6.png')  # 读取图像
gray1 = cv.cvtColor(img1, cv.COLOR_BGR2GRAY)  # 转换灰度图像
gray2 = cv.cvtColor(img2, cv.COLOR_BGR2GRAY)  # 转换灰度图像
hist1 = cv.calcHist([gray1], [0], None, [256], [0, 256])  # 计算灰度直方图
hist2 = cv.calcHist([gray2], [0], None, [256], [0, 256])  # 计算灰度直方图

cv.imshow('pic2', img1)  # 运行结果:  https://gitee.com/skyrookieyu/csdn_ai25_week2/blob/master/3_1.JPG
cv.imshow('pic6', img2)  # 运行结果:  https://gitee.com/skyrookieyu/csdn_ai25_week2/blob/master/3_2.JPG

# 显示 hist1 灰度直方图
plt.plot(hist1)  # 绘制灰度直方图
plt.xlim([0, 256])  # 图像参数，绘制 X 轴的刻度
plt.title("Pic2__Histogram")  # 直方图标题
plt.show()  # 运行结果:  https://gitee.com/skyrookieyu/csdn_ai25_week2/blob/master/3_3.JPG

# 显示 hist2 灰度直方图
plt.plot(hist2)  # 绘制灰度直方图
plt.xlim([0, 256])  # 图像参数，绘制 X 轴的刻度
plt.title("Pic6_Histogram")  # 直方图标题
plt.show()  # 运行结果:  https://gitee.com/skyrookieyu/csdn_ai25_week2/blob/master/3_4.JPG

# pic2 大津算法阈值分割
Gauss_pic2 = cv.GaussianBlur(gray1, (5, 5), 0)  # 高斯滤波
_, gray_OTSU_pic2 = cv.threshold(Gauss_pic2, 125, 255, cv.THRESH_OTSU)  # 大津算法阈值分割
element_pic2 = cv.getStructuringElement(cv.MORPH_CROSS, (3,3))  # 数学形态学滤波
pic2 = cv.morphologyEx(gray_OTSU_pic2, cv.MORPH_OPEN, element_pic2)  # 开运算滤波
cv.imshow("Pic2_OTSU", pic2)  # 显示 pic2 经大津算法分割的图像 运行结果:  https://gitee.com/skyrookieyu/csdn_ai25_week2/blob/master/3_5.JPG

# pic6 大津算法阈值分割
Gauss_pic6 = cv.GaussianBlur(gray2, (5, 5), 0)  # 高斯滤波
_, gray_OTSU_pic6 = cv.threshold(Gauss_pic6, 125, 255, cv.THRESH_BINARY)  # 大津算法阈值分割
element_pic6 = cv.getStructuringElement(cv.MORPH_CROSS, (3,3))  # 数学形态学滤波
pic6 = cv.morphologyEx(gray_OTSU_pic6, cv.MORPH_OPEN, element_pic6)  # 开运算滤波
cv.imshow("Pic6_OTSU", pic6)  # 显示 pic6 经大津算法分割的图像 运行结果:  https://gitee.com/skyrookieyu/csdn_ai25_week2/blob/master/3_6.JPG

cv.waitKey()
cv.destroyAllWindows()

######### ----------------------------------------  #########

# coding=utf-8
"""

4. 使用米粒图像，分割得到各米粒，首先计算各区域(米粒)的面积、长度等信息，进一步计算面积、长度的均值及方差，分析落在3sigma范围内米粒的数量。
结果分析：（摘要）（完整数据在最下方）
（米粒面积不足 10 的视为噪声忽略不计）
米粒总数量:  93
------------------------------
总面积: 14130.5
平均面积: 151.94086021505376
面积方差： 3877.7411261417515
面积标准差: 62.27151135263823
面积 3-Sigma 的取值范围: -34.874 - 338.76
米粒面积在 3-Sigma 内的数量为: 91
米粒面积在 3-Sigma 内的比例为: 97.849%
------------------------------
平均长度: 19.913978494623656
长度方差: 50.573245461903106
长度标准差: 7.111486867168012
平均宽度: 17.548387096774192
宽度方差: 57.15088449531738
宽度标准差: 7.559820400996136

"""

import cv2 as cv
import copy
import numpy as np

RiceFilename = r'rice.png'
AreaThreshold = 10
image = cv.imread(RiceFilename)
gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
_, bw = cv.threshold(gray, 0, 255, cv.THRESH_OTSU)
element = cv.getStructuringElement(cv.MORPH_CROSS, (3, 3))  # 用于形态学的的算子构建，第一个参数便是内核的形状（矩形，交叉形，椭圆形）
bw = cv.morphologyEx(bw, cv.MORPH_OPEN, element)  # 数学形态学去噪

#cv.imshow("Source", image)
#cv.imshow("Gray", bw)

seg = copy.deepcopy(bw)
bin, cnts, hier = cv.findContours(seg, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
count = 0
areas = []
widths = []
heights = []

for i in range(len(cnts), 0, -1):
    cnt = cnts[i-1]
    area = cv.contourArea(cnt)
    if area < AreaThreshold:
        continue
    count = count + 1
    areas.append(area)


    #minAreaRect = cv.minAreaRect(cnt)
    #x, y, w, h = cv.boxPoints(minAreaRect)

    x, y, w, h = cv.boundingRect(cnt)
    widths.append(w)
    heights.append(h)
    print("Grain ", i, " : Area = {}, Width = {}, Height = {}".format(area, w, h))
    cv.rectangle(image, (x,y), (x+w, y+h), (0, 0, 0xff), 1)
    cv.putText(image, str(count), (x, y), cv.FONT_HERSHEY_PLAIN, 0.5, (0, 0xff, 0))


cv.imshow("Source", image)  # 运行结果:  https://gitee.com/skyrookieyu/csdn_ai25_week2/blob/master/4_1.JPG
cv.imshow("Gray", bw)  # 运行结果:  https://gitee.com/skyrookieyu/csdn_ai25_week2/blob/master/4_2.JPG

print("Number of grains(Area Threshold - {}): {}".format(AreaThreshold, count) )
print("Sum of grain areas: ", np.sum(areas))

meanOfAreas = np.mean(areas)
print("Average grain area：", meanOfAreas)
print("Average grain width：", np.mean(widths))
print("Average grain height：", np.mean(heights))

print("Variance of grain areas：", np.var(areas))
print("Variance of grain widths：", np.var(widths))
print("Variance of grain heights：", np.var(heights))

SD = np.std(areas)
print("SD of grain areas：", SD)
print("SD of grain widths：", np.std(widths))
print("SD of grain heights：", np.std(heights))

numbOfAreasWithin3Simgas = 0
for area in areas:
    if abs(area - meanOfAreas) <= 3*SD :
        numbOfAreasWithin3Simgas += 1

print("3-Sigma inverval: {:.5} - {:.5} ".format(meanOfAreas - 3*SD, meanOfAreas + 3*SD))
print("Number of grain areas wighin 3 sigmas：", numbOfAreasWithin3Simgas)
print("{:.5}% ".format(numbOfAreasWithin3Simgas/count*100))
cv.waitKey()
cv.destroyAllWindows()

"""

Grain  95  : Area = 47.0, Width = 10, Height = 9
Grain  94  : Area = 112.5, Width = 18, Height = 14
Grain  93  : Area = 163.0, Width = 11, Height = 25
Grain  91  : Area = 11.0, Width = 7, Height = 4
Grain  90  : Area = 103.0, Width = 13, Height = 18
Grain  89  : Area = 165.5, Width = 19, Height = 21
Grain  88  : Area = 35.0, Width = 10, Height = 7
Grain  87  : Area = 76.0, Width = 7, Height = 16
Grain  86  : Area = 99.0, Width = 20, Height = 10
Grain  85  : Area = 176.0, Width = 13, Height = 28
Grain  84  : Area = 123.0, Width = 14, Height = 21
Grain  83  : Area = 157.0, Width = 9, Height = 28
Grain  82  : Area = 169.5, Width = 16, Height = 23
Grain  81  : Area = 187.0, Width = 26, Height = 16
Grain  80  : Area = 167.0, Width = 11, Height = 27
Grain  79  : Area = 375.0, Width = 42, Height = 23
Grain  78  : Area = 117.5, Width = 13, Height = 22
Grain  77  : Area = 168.5, Width = 21, Height = 18
Grain  76  : Area = 141.5, Width = 18, Height = 18
Grain  75  : Area = 161.0, Width = 27, Height = 11
Grain  74  : Area = 202.0, Width = 29, Height = 12
Grain  73  : Area = 185.0, Width = 20, Height = 23
Grain  72  : Area = 178.5, Width = 28, Height = 15
Grain  71  : Area = 180.0, Width = 25, Height = 17
Grain  70  : Area = 133.0, Width = 19, Height = 17
Grain  69  : Area = 162.0, Width = 13, Height = 26
Grain  68  : Area = 139.5, Width = 15, Height = 21
Grain  67  : Area = 170.5, Width = 13, Height = 29
Grain  66  : Area = 200.0, Width = 21, Height = 26
Grain  65  : Area = 162.5, Width = 13, Height = 26
Grain  64  : Area = 106.0, Width = 13, Height = 17
Grain  63  : Area = 167.0, Width = 21, Height = 20
Grain  62  : Area = 180.0, Width = 10, Height = 29
Grain  61  : Area = 192.5, Width = 9, Height = 31
Grain  60  : Area = 181.0, Width = 24, Height = 21
Grain  59  : Area = 174.5, Width = 13, Height = 26
Grain  58  : Area = 359.5, Width = 38, Height = 27
Grain  57  : Area = 89.0, Width = 14, Height = 12
Grain  56  : Area = 47.0, Width = 4, Height = 23
Grain  55  : Area = 192.5, Width = 27, Height = 13
Grain  54  : Area = 190.5, Width = 23, Height = 23
Grain  53  : Area = 213.0, Width = 23, Height = 25
Grain  52  : Area = 215.5, Width = 18, Height = 28
Grain  51  : Area = 192.0, Width = 10, Height = 28
Grain  50  : Area = 158.5, Width = 25, Height = 17
Grain  49  : Area = 333.5, Width = 34, Height = 30
Grain  48  : Area = 146.0, Width = 13, Height = 27
Grain  47  : Area = 168.5, Width = 28, Height = 12
Grain  46  : Area = 156.5, Width = 10, Height = 29
Grain  45  : Area = 181.0, Width = 10, Height = 28
Grain  44  : Area = 201.0, Width = 28, Height = 16
Grain  43  : Area = 161.0, Width = 10, Height = 29
Grain  42  : Area = 170.5, Width = 20, Height = 20
Grain  41  : Area = 175.5, Width = 9, Height = 29
Grain  40  : Area = 194.0, Width = 19, Height = 27
Grain  39  : Area = 146.0, Width = 26, Height = 10
Grain  38  : Area = 199.0, Width = 9, Height = 31
Grain  37  : Area = 155.5, Width = 22, Height = 12
Grain  36  : Area = 190.5, Width = 30, Height = 12
Grain  35  : Area = 133.5, Width = 20, Height = 16
Grain  34  : Area = 157.5, Width = 9, Height = 27
Grain  33  : Area = 192.0, Width = 26, Height = 20
Grain  32  : Area = 175.0, Width = 22, Height = 24
Grain  31  : Area = 191.0, Width = 30, Height = 9
Grain  30  : Area = 128.0, Width = 17, Height = 22
Grain  29  : Area = 164.0, Width = 8, Height = 29
Grain  28  : Area = 94.5, Width = 13, Height = 16
Grain  27  : Area = 242.0, Width = 26, Height = 33
Grain  26  : Area = 170.0, Width = 22, Height = 23
Grain  25  : Area = 181.0, Width = 13, Height = 28
Grain  24  : Area = 154.0, Width = 14, Height = 25
Grain  23  : Area = 180.0, Width = 20, Height = 22
Grain  22  : Area = 172.5, Width = 15, Height = 27
Grain  21  : Area = 61.0, Width = 13, Height = 7
Grain  20  : Area = 160.5, Width = 27, Height = 10
Grain  19  : Area = 193.5, Width = 23, Height = 22
Grain  18  : Area = 160.0, Width = 12, Height = 28
Grain  17  : Area = 133.5, Width = 19, Height = 16
Grain  16  : Area = 134.5, Width = 26, Height = 14
Grain  15  : Area = 134.0, Width = 12, Height = 23
Grain  14  : Area = 176.0, Width = 19, Height = 22
Grain  13  : Area = 156.0, Width = 24, Height = 16
Grain  12  : Area = 154.0, Width = 23, Height = 11
Grain  11  : Area = 72.0, Width = 8, Height = 18
Grain  10  : Area = 130.5, Width = 17, Height = 23
Grain  8  : Area = 42.0, Width = 14, Height = 8
Grain  7  : Area = 45.5, Width = 16, Height = 5
Grain  6  : Area = 41.0, Width = 8, Height = 17
Grain  5  : Area = 77.5, Width = 12, Height = 19
Grain  4  : Area = 14.5, Width = 7, Height = 7
Grain  3  : Area = 84.0, Width = 16, Height = 14
Grain  2  : Area = 89.5, Width = 7, Height = 19
Grain  1  : Area = 31.0, Width = 13, Height = 9
Number of grains(Area Threshold - 10): 93
Sum of grain areas:  14130.5
Average grain area： 151.94086021505376
Average grain width： 17.548387096774192
Average grain height： 19.913978494623656
Variance of grain areas： 3877.7411261417515
Variance of grain widths： 57.15088449531738
Variance of grain heights： 50.573245461903106
SD of grain areas： 62.27151135263823
SD of grain widths： 7.559820400996136
SD of grain heights： 7.111486867168012
3-Sigma inverval: -34.874 - 338.76 
Number of grain areas wighin 3 sigmas： 91
97.849% 

"""

######### ----------------------------------------  #########

# coding=utf-8
"""

5. 使用棋盘格及自选风景图像，分别使用SIFT、FAST及ORB算子检测角点，并比较分析检测结果。
(可选)使用Harris角点检测算子检测棋盘格，并与上述结果比较。
结果分析:
1) SIFT: SIFT旋转检测较为精准，但是检测速度较慢，相对的角点检测效果很好，之后的很多角点检测算子都是根据SIFT角点检测提出的，并且进行了提速等优化。
2) FAST: FAST算法算法速度较快，由SIFT算法改进而来，抗噪声的能力相对较弱，角点判断容易出错。FAST的提出者 Rosten 等将FAST角点定义为：若某像素与其周围邻域内足够多的像素点相差较大，则该像素可能是角点。
3) ORB: ORB算法检测速度较快效果也精准，ORB = oFAST + rBRIEF (oFAST是由FAST算法改进)，在使用oFAST提取出特征点之后，为其定义一个特征点方向，以此来实现特征点的旋转不变性。
4) Harris 角点检测效果也还不错，但也存在很多漏检的角。
5）从代码运行结果来看，FAST 角点检测误检比较多，但基本上所以的角点都检测出来了，SIFT 角点检测效果要略好于 FAST，而 ORB 的角点检测是基于改进的 FAST，所以检测效果要好一点，但存在漏检的情况。Harris与前三者相比，效果与速度都介于中间可接受范围。

"""
# SIFT

import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt

ChessboardFilename = r'left03.jpg'
BuildingFilename = r'St_MaryHelpChristiansChurch-185.jpg'
sift = cv.xfeatures2d.SIFT_create()
sift2 = cv.xfeatures2d.SIFT_create()
img = cv.imread(ChessboardFilename)
img2 = cv.imread(BuildingFilename)
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
gray2 = cv.cvtColor(img2, cv.COLOR_BGR2GRAY)
kp, des = sift.detectAndCompute(img, None)
kp2, des2 = sift2.detectAndCompute(img2, None)
plt.figure(figsize=(15, 15))
plt.subplot(2, 2, 1)
plt.title("Chessboard_gray")
plt.imshow(gray, cmap="gray")  # 运行结果:  https://gitee.com/skyrookieyu/csdn_ai25_week2/blob/master/5_1.JPG
plt.subplot(2, 2, 3)
plt.title("Building_gray")
plt.imshow(gray2, cmap="gray")  # 运行结果:  https://gitee.com/skyrookieyu/csdn_ai25_week2/blob/master/5_1.JPG

# cv2.imshow('gray',gray)
# cv2.waitKey(0)

img1 = cv.drawKeypoints(img, kp, img, color=(255, 0, 255))
img3 = cv.drawKeypoints(img2, kp2, img2, color=(255, 0, 255))
plt.subplot(2, 2, 2), plt.title("Chessboard_points")
plt.imshow(img1)  # 运行结果:  https://gitee.com/skyrookieyu/csdn_ai25_week2/blob/master/5_1.JPG
plt.subplot(2, 2, 4), plt.title("Building_points")
plt.imshow(img3)  # 运行结果:  https://gitee.com/skyrookieyu/csdn_ai25_week2/blob/master/5_1.JPG
plt.show()


# FAST

import cv2 as cv
import matplotlib.pyplot as plt

ChessboardFilename = r'left03.jpg'
BuildingFilename = r'St_MaryHelpChristiansChurch-185.jpg'
cimg = cv.imread(ChessboardFilename)
bimg = cv.imread(BuildingFilename)
fast = cv.FastFeatureDetector_create()
# fast_1 = cv.FastFeatureDetector_create()
kp_c = fast.detect(cimg, None)
kp_b = fast.detect(bimg, None)
cimg_kp = cv.drawKeypoints(cimg, kp_c, None, color=(255, 0, 0))
bimg_kp = cv.drawKeypoints(bimg, kp_b, None, color=(255, 0, 0))
# fast.setNonmaxSuppression(0)  # 这个是取消fast算法里面的非极大值抑制
# kp = fast.detect(img,None)
# img2 = cv.drawKeypoints(img, kp, None, color=(255,0,0))
plt.figure(figsize=(15,15))
plt.subplot(2, 2, 1)，plt.title("Chessboard_Gray")
plt.imshow(cimg, cmap="gray")  # 运行结果:  https://gitee.com/skyrookieyu/csdn_ai25_week2/blob/master/5_2.JPG
plt.subplot(2, 2, 2), plt.title("Chessboard_FAST")
plt.imshow(cimg_kp)  # 运行结果:  https://gitee.com/skyrookieyu/csdn_ai25_week2/blob/master/5_2.JPG
plt.subplot(2, 2, 3), plt.title("Building_Gray")
plt.imshow(bimg, cmap="gray")  # 运行结果:  https://gitee.com/skyrookieyu/csdn_ai25_week2/blob/master/5_2.JPG
plt.subplot(2, 2, 4), plt.title("Buliding_FAST")
plt.imshow(bimg_kp)  # 运行结果:  https://gitee.com/skyrookieyu/csdn_ai25_week2/blob/master/5_2.JPG
plt.show()


# ORB

import cv2 as cv
import matplotlib.pyplot as plt

ChessboardFilename = r'left03.jpg'
BuildingFilename = r'St_MaryHelpChristiansChurch-185.jpg'
bimg = cv.imread(BuildingFilename, cv.IMREAD_GRAYSCALE)
cimg = cv.imread(ChessboardFilename, cv.IMREAD_GRAYSCALE)
orb = cv.ORB_create()
# fast_1 = cv.FastFeatureDetector_create()
kp_c, dest_c = orb.detectAndCompute(cimg, None)
kp_b, dest_b = orb.detectAndCompute(bimg, None)
cimg_kp = cv.drawKeypoints(cimg, kp_c, None, color=(255, 0, 255))
bimg_kp = cv.drawKeypoints(bimg, kp_b, None, color=(255, 0, 255))
# fast.setNonmaxSuppression(0)  # 这个是取消fast算法里面的非极大值抑制
# kp = fast.detect(img,None)
# img2 = cv.drawKeypoints(img, kp, None, color=(255,0,0))
plt.figure(figsize=(15,15))
plt.subplot(2, 2, 1), plt.title("Chessboard_Gray")
plt.imshow(cimg, cmap="gray")  # 运行结果:  https://gitee.com/skyrookieyu/csdn_ai25_week2/blob/master/5_3.JPG
plt.subplot(2, 2, 2), plt.title("Chessboard_ORB")
plt.imshow(cimg_kp)  # 运行结果:  https://gitee.com/skyrookieyu/csdn_ai25_week2/blob/master/5_3.JPG
plt.subplot(2, 2, 3),plt.title("Building_Gray")
plt.imshow(bimg, cmap="gray")  # 运行结果:  https://gitee.com/skyrookieyu/csdn_ai25_week2/blob/master/5_3.JPG
plt.subplot(2, 2, 4),plt.title("Buliding_ORB")
plt.imshow(bimg_kp)  # 运行结果:  https://gitee.com/skyrookieyu/csdn_ai25_week2/blob/master/5_3.JPG
plt.show()


# Harris

import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt

ChessboardFilename = r'left03.jpg'
BuildingFilename = r'St_MaryHelpChristiansChurch-185.jpg'
cimg = cv.imread(ChessboardFilename)
#bimg = cv.imread(BuildingFilename)
cgray = cv.cvtColor(cimg, cv.COLOR_BGR2GRAY)
#bgray = cv.cvtColor(bimg, cv.COLOR_BGR2GRAY)

#图像转换为 float32
cgray = np.float32(cgray)
#bgray = np.float32(bgray)

dst_c = cv.cornerHarris(cgray, 2, 3, 0.06)   # 0.04是角点响应函数里面的系数，属于经验值一般取0.04-0.06
#dst_b = cv.cornerHarris(bgray, 2, 3, 0.06)

#cv.imshow("Chessboard_Harris", dst_c)
#cv.imshow("Building_Harris", dst_b)
#cv.waitKey()
#cv.destroyAllWindows()  # 直接用Harris角点检测出来的图基本上看不到什么，所以需要进行进一步处理

dst_c = cv.dilate(dst_c, None)  # 图像膨胀 目的是把角点的标记变大些
dst_c = cv.dilate(dst_c, None)
#dst_b = cv.dilate(dst_b, None)
#dst_b = cv.dilate(dst_b, None)

# 这里以大于 0.1*dst 中最大值为边界
cimg[dst_c > 0.1*dst_c.max()] = [255, 0, 0]  # 角点位置用红色标记
#bimg[dst_b > 0.01*dst_b.max()]=[255, 0, 0]  # 角点位置用红色标记

plt.figure(figsize=(15, 15))
plt.subplot(2, 2, 1), plt.title("Chessboard_Gray")
plt.imshow(cgray, cmap="gray")  # 运行结果:  https://gitee.com/skyrookieyu/csdn_ai25_week2/blob/master/5_4.JPG
plt.subplot(2, 2, 2), plt.title("Chessboard_Harris")
plt.imshow(cimg)  # 运行结果:  https://gitee.com/skyrookieyu/csdn_ai25_week2/blob/master/5_4.JPG
plt.show()
